<template>
  <div class="component page">
    <div class="container-center">
      <div class="over-hidden">
        <router-link
          class="btn btn-default pull-right icon icon-arrowsleftline mt-lg"
          :to="getMicroRoute('/tools')"
        >
          返回列表</router-link>
        <h2 class="text-left">流程图</h2>
      </div>
      <div class="over-hidden">
        <div class="btns-row" style="padding: 12px 0">
          <a @click="handleImportData" class="btn btn-default mr-md">导入数据</a>
          <a @click="handleExportData" class="btn btn-default mr-md">导出数据</a>
          <a @click="handleExportImage" class="btn btn-default mr-md">导出图片</a>
          <a @click="handleReset" class="btn btn-default mr-md">重置画布</a>
          <a @click="handleClear" class="btn btn-default mr-md">清空画布</a>
          <div style="float:right;color:#999;line-height:34px;">提示: 画布空白区域、节点上、连线上使用右键调用菜单</div>
        </div>
        <div ref="flow_container" class="super-flow-base-demo">
          <super-flow
            ref="superFlow"
            :node-list="nodeList"
            :link-list="linkList"
            :origin="origin"
            :graph-menu="graphMenuList"
            :node-menu="nodeMenuList"
            :link-menu="linkMenuList"
            :enter-intercept="enterIntercept"
            :output-intercept="outputIntercept"
            :link-desc="linkDesc">
            <template v-slot:node="{meta}">
              <div :class="`flow-node flow-node-${meta.prop}`">
                <header>
                  {{meta.name}}
                </header>
                <section>
                  {{meta.desc}}
                </section>
              </div>
            </template>
          </super-flow>
        </div>
      </div>
    </div>
    <DialogerComp ref="importView" title="导入" @sure="handleImportConfirm" width="600px">
      <template v-slot:body>
        <div class="form-group">
          <label class="form-label">
            JSON配置:
          </label>
          <textarea
            class="form-textarea"
            v-model="importData"
          ></textarea>
        </div>
      </template>
    </DialogerComp>
    <DialogerComp ref="editView" title="编辑" @sure="handleSave" width="500px">
      <template v-slot:body>
        <div class="form-group">
          <label class="form-label">
            节点名称:
          </label>
          <input
            type="text" class="form-input"
            v-model="editNode.meta.name"
          />
        </div>
        <div class="form-group">
          <label class="form-label">
            节点描述:
          </label>
          <input
            type="text" class="form-input"
            v-model="editNode.meta.desc"
          />
        </div>
        <div class="form-group">
          <label class="form-label">
            宽度:
          </label>
          <input
            type="text" class="form-input"
            v-model="editNode.width"
          />
        </div>
        <div class="form-group">
          <label class="form-label">
            高度:
          </label>
          <input
            type="text" class="form-input"
            v-model="editNode.height"
          />
        </div>
      </template>
    </DialogerComp>
  </div>
</template>

<script>
import SuperFlow from 'vue-super-flow/lib/index.umd.min'
import { filer, imager } from '@daelui/dogjs/dist/components'
import DialogerComp from '../../../components/dialoger/dialoger.vue'
import dialoger from '../../../components/dialoger/dialoger.js'

const drawerType = {
  node: 0,
  link: 1
}
/* JSON转换 */
export default {
  components: {
    SuperFlow,
    DialogerComp
  },
  data () {
    return {
      config: {
        dir: 'vertical', // 排列形式
        prefix: '', // 前缀
        gapWidth: 2 // 间隔距离
      },
      drawerType,
      drawerConf: {
        title: '',
        visible: false,
        type: null,
        info: null,
        open: (type, info) => {
          const conf = this.drawerConf
          conf.visible = true
          conf.type = type
          conf.info = info
          if (conf.type === drawerType.node) {
            conf.title = '节点'
            if (this.$refs.nodeSetting) this.$refs.nodeSetting.resetFields()
            this.$set(this.nodeSetting, 'name', info.meta.name)
            this.$set(this.nodeSetting, 'desc', info.meta.desc)
          } else {
            conf.title = '连线'
            if (this.$refs.linkSetting) this.$refs.linkSetting.resetFields()
            this.$set(this.linkSetting, 'desc', info.meta ? info.meta.desc : '')
          }
        },
        cancel: () => {
          this.drawerConf.visible = false
          if (this.drawerConf.type === drawerType.node) {
            this.$refs.nodeSetting.clearValidate()
          } else {
            this.$refs.linkSetting.clearValidate()
          }
        }
      },
      linkSetting: {
        desc: ''
      },
      nodeSetting: {
        name: '',
        desc: ''
      },

      origin: [681, 465],
      nodeList: [],
      linkList: [],
      // 画布菜单
      graphMenuList: [
        [
          {
            label: '开始节点',
            disable (graph) {
              return !!graph.nodeList.find(node => node.meta.prop === 'start')
            },
            selected: (graph, coordinate) => {
              const start = graph.nodeList.find(node => node.meta.prop === 'start')
              if (!start) {
                graph.addNode({
                  width: 100,
                  height: 80,
                  coordinate: coordinate,
                  meta: {
                    prop: 'start',
                    name: '开始节点'
                  }
                })
              }
            }
          },
          {
            label: '条件节点',
            disable: false,
            selected: (graph, coordinate) => {
              graph.addNode({
                width: 160,
                height: 80,
                coordinate: coordinate,
                meta: {
                  prop: 'condition',
                  name: '条件节点'
                }
              })
            }
          },
          {
            label: '审批节点',
            disable: false,
            selected: (graph, coordinate) => {
              graph.addNode({
                width: 160,
                height: 80,
                coordinate: coordinate,
                meta: {
                  prop: 'approval',
                  name: '审批节点'
                }
              })
            }
          },
          {
            label: '抄送节点',
            disable: false,
            selected: (graph, coordinate) => {
              graph.addNode({
                width: 160,
                height: 80,
                coordinate: coordinate,
                meta: {
                  prop: 'cc',
                  name: '抄送节点'
                }
              })
            }
          },
          {
            label: '结束节点',
            disable (graph) {
              return !!graph.nodeList.find(point => point.meta.prop === 'end')
            },
            selected: (graph, coordinate) => {
              graph.addNode({
                width: 80,
                height: 50,
                coordinate: coordinate,
                meta: {
                  prop: 'end',
                  name: '结束节点'
                }
              })
            }
          }
        ],
        [
          {
            label: '打印数据',
            selected: (graph, coordinate) => {
              console.log(JSON.stringify(graph.toJSON(), null, 2))
            }
          },
          {
            label: '全选',
            selected: (graph, coordinate) => {
              graph.selectAll()
            }
          }
        ]
      ],
      // 节点菜单
      nodeMenuList: [
        [
          {
            label: '删除',
            disable: false,
            hidden (node) {
              return node.meta.prop === 'start'
            },
            selected (node, coordinate) {
              node.remove()
            }
          }
        ],
        [
          {
            label: '编辑',
            selected: (node, coordinate) => {
              console.log(node, coordinate)
              this.currentNode = node
              this.editNode = JSON.parse(JSON.stringify(node))
              this.$refs.editView.show()
            }
          }
        ]
      ],
      // 连线菜单
      linkMenuList: [
        [
          {
            label: '删除',
            disable: false,
            selected: (link, coordinate) => {
              link.remove()
            }
          }
        ]
        // [
        //   {
        //     label: '编辑',
        //     disable: false,
        //     selected: (link, coordinate) => {
        //       console.log(link, coordinate)
        //     }
        //   }
        // ]
      ],

      // 当前操作的节点
      currentNode: {},
      editNode: {
        meta: {
          name: '',
          desc: ''
        }
      },
      // 导入数据
      importData: ''
    }
  },

  methods: {
    /**
     * @description 初始化
     */
    init () {
      const nodeList = [
        {
          'id': 'nodeS3WgFnzCI15X58Qw',
          'width': 100,
          'height': 80,
          'coordinate': [
            -648,
            -148
          ],
          'meta': {
            'prop': 'start',
            'name': '开始节点'
          }
        },
        {
          'id': 'nodeG3WeFnzCI15X58Qw',
          'width': 160,
          'height': 80,
          'coordinate': [
            -486,
            -148
          ],
          'meta': {
            'prop': 'condition',
            'name': '条件节点'
          }
        },
        {
          'id': 'node0aiA9VuhjkiAdZCs',
          'width': 160,
          'height': 80,
          'coordinate': [
            -253,
            -148
          ],
          'meta': {
            'prop': 'approval',
            'name': '审批节点'
          }
        },
        {
          'id': 'nodesyxisLH1hJDdPsxx',
          'width': 160,
          'height': 80,
          'coordinate': [
            -19,
            -148
          ],
          'meta': {
            'prop': 'cc',
            'name': '抄送节点'
          }
        },
        {
          'id': 'nodeDhVU6w2KbEnJCjZs',
          'width': 80,
          'height': 50,
          'coordinate': [
            199,
            -133
          ],
          'meta': {
            'prop': 'end',
            'name': '结束节点'
          }
        }
      ]
      const linkList = [
        {
          'id': 'linkMvLA3NDQLBOYaOwK',
          'startId': 'nodeS3WgFnzCI15X58Qw',
          'endId': 'nodeG3WeFnzCI15X58Qw',
          'startAt': [
            100,
            40
          ],
          'endAt': [
            0,
            40
          ],
          'meta': null
        },
        {
          'id': 'link8OlDGVydEq4sq4UD',
          'startId': 'nodesyxisLH1hJDdPsxx',
          'endId': 'nodeDhVU6w2KbEnJCjZs',
          'startAt': [
            160,
            40
          ],
          'endAt': [
            0,
            25
          ],
          'meta': null
        },
        {
          'id': 'linkxB3Eo9hSUwu7SQeZ',
          'startId': 'node0aiA9VuhjkiAdZCs',
          'endId': 'nodesyxisLH1hJDdPsxx',
          'startAt': [
            160,
            40
          ],
          'endAt': [
            0,
            40
          ],
          'meta': null
        },
        {
          'id': 'linkDFiYxHKYiml3ceG6',
          'startId': 'nodeG3WeFnzCI15X58Qw',
          'endId': 'node0aiA9VuhjkiAdZCs',
          'startAt': [
            160,
            40
          ],
          'endAt': [
            0,
            40
          ],
          'meta': null
        }
      ]
      // const nodeList = [
      //     {
      //       'id': 'nodeS3WgFnzCI15X58Qw',
      //       'width': 100,
      //       'height': 80,
      //       'coordinate': [-644, -148],
      //       'meta': {
      //         'prop': 'start',
      //         'name': '开始节点'
      //       }
      //     },
      //     {
      //       'id': 'nodefHsy9uJObPtdHZv1',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [-200, -148],
      //       'meta': {
      //         'prop': 'approval',
      //         'name': '审批节点',
      //         'desc': '111111'
      //       }
      //     },
      //     {
      //       'id': 'nodeni9QOqT3mI7hsMau',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [-442, -275],
      //       'meta': {
      //         'prop': 'condition',
      //         'name': '条件节点'
      //       }
      //     },
      //     {
      //       'id': 'nodeZBK0ZPpgMe1exezE',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [-200, -275],
      //       'meta': {
      //         'prop': 'approval',
      //         'name': '审批节点'
      //       }
      //     },
      //     {
      //       'id': 'nodeqkK9zjcDz53xKRlK',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [34, -209],
      //       'meta': {
      //         'prop': 'cc',
      //         'name': '抄送节点'
      //       }
      //     },
      //     {
      //       'id': 'nodeDhVU6w2KbEnJCjZs',
      //       'width': 80,
      //       'height': 50,
      //       'coordinate': [286, -133],
      //       'meta': {
      //         'prop': 'end',
      //         'name': '结束节点'
      //       }
      //     },
      //     {
      //       'id': 'nodesyxisLH1hJDdPsxx',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [34, -75],
      //       'meta': {
      //         'prop': 'cc',
      //         'name': '抄送节点'
      //       }
      //     },
      //     {
      //       'id': 'node0aiA9VuhjkiAdZCs',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [-200, -2],
      //       'meta': {
      //         'prop': 'approval',
      //         'name': '审批节点'
      //       }
      //     },
      //     {
      //       'id': 'nodeG3WeFnzCI15X58Qw',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [-442, -2],
      //       'meta': {
      //         'prop': 'condition',
      //         'name': '条件节点'
      //       }
      //     },
      //     {
      //       'id': 'node7WXbwOR6kSFD53Hf',
      //       'width': 160,
      //       'height': 80,
      //       'coordinate': [-442, -148],
      //       'meta': {
      //         'prop': 'condition',
      //         'name': '条件节点'
      //       }
      //     }
      //   ]
      // const linkList = [
      //   {
      //     'id': 'linkcs9ZhumWeTHrtUy8',
      //     'startId': 'nodeS3WgFnzCI15X58Qw',
      //     'endId': 'nodeni9QOqT3mI7hsMau',
      //     'startAt': [100, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'linkBDld5rDBw4C6kiva',
      //     'startId': 'nodefHsy9uJObPtdHZv1',
      //     'endId': 'nodeqkK9zjcDz53xKRlK',
      //     'startAt': [160, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'linkA0ZZxRlDI9AOonuq',
      //     'startId': 'node7WXbwOR6kSFD53Hf',
      //     'endId': 'nodefHsy9uJObPtdHZv1',
      //     'startAt': [160, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'linkhCKTpRAf89gcujGS',
      //     'startId': 'nodeni9QOqT3mI7hsMau',
      //     'endId': 'nodeZBK0ZPpgMe1exezE',
      //     'startAt': [160, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'link2o7VZ7DRaSFKtB0g',
      //     'startId': 'nodeqkK9zjcDz53xKRlK',
      //     'endId': 'nodeDhVU6w2KbEnJCjZs',
      //     'startAt': [160, 40],
      //     'endAt': [0, 25],
      //     'meta': null
      //   },
      //   {
      //     'id': 'linkII013ovDctUDuPLu',
      //     'startId': 'nodeS3WgFnzCI15X58Qw',
      //     'endId': 'nodeG3WeFnzCI15X58Qw',
      //     'startAt': [100, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'link6MOmsq1EqzlWcG1n',
      //     'startId': 'nodeZBK0ZPpgMe1exezE',
      //     'endId': 'nodeqkK9zjcDz53xKRlK',
      //     'startAt': [160, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'link52SczSXHmuyKDzRU',
      //     'startId': 'nodesyxisLH1hJDdPsxx',
      //     'endId': 'nodeDhVU6w2KbEnJCjZs',
      //     'startAt': [160, 40],
      //     'endAt': [0, 25],
      //     'meta': null
      //   },
      //   {
      //     'id': 'link2hBQDTuIG4ZFYyE0',
      //     'startId': 'node0aiA9VuhjkiAdZCs',
      //     'endId': 'nodesyxisLH1hJDdPsxx',
      //     'startAt': [160, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'linkrwdW87FmOma5rPVo',
      //     'startId': 'nodeG3WeFnzCI15X58Qw',
      //     'endId': 'node0aiA9VuhjkiAdZCs',
      //     'startAt': [160, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   },
      //   {
      //     'id': 'linknL75dQV0AWZA85sq',
      //     'startId': 'nodeS3WgFnzCI15X58Qw',
      //     'endId': 'node7WXbwOR6kSFD53Hf',
      //     'startAt': [100, 40],
      //     'endAt': [0, 40],
      //     'meta': null
      //   }
      // ]
      setTimeout(() => {
        this.nodeList = nodeList
        this.linkList = linkList
      }, 100)
    },
    enterIntercept (formNode, toNode, graph) {
      const formType = formNode.meta.prop
      switch (toNode.meta.prop) {
        case 'start':
          return false
        case 'approval':
          return [
            'start',
            'approval',
            'condition',
            'cc'
          ].includes(formType)
        case 'condition':
          return [
            'start',
            'approval',
            'condition',
            'cc'
          ].includes(formType)
        case 'end':
          return [
            'approval',
            'cc'
          ].includes(formType)
        default:
          return true
      }
    },
    outputIntercept (node, graph) {
      return !(node.meta.prop === 'end')
    },
    linkDesc (link) {
      return link.meta ? link.meta.desc : ''
    },

    /**
     * @function 编辑节点保存
    */
    handleSave () {
      Object.assign(this.currentNode, this.editNode)
      this.$refs.editView.hide()
    },

    /**
     * @description 导入数据
     */
    handleImportData () {
      this.$refs.importView.show()
    },

    /**
     * @description 导入确认
     */
    handleImportConfirm () {
      let importData = this.importData
      if (/\[|\[/.test(importData)) {
        let data = {}
        try {
          data = (new Function('return ' + importData))()
        } catch (e) {}
        this.nodeList = Array.isArray(data.nodeList) ? data.nodeList : this.nodeList
        this.linkList = Array.isArray(data.linkList) ? data.linkList : this.linkList
      }
    },

    /**
     * @description 导出数据
     */
    handleExportData () {
      let graph = this.$refs.superFlow.graph
      filer.downloadFile(new Date().getTime() + '.json', JSON.stringify({
        origin: graph.origin,
        nodeList: graph.nodeList,
        linkList: graph.linkList
      }, null, 2))
    },

    /**
     * @description 导出图片
     */
    handleExportImage () {
      imager.convertToCanvas(this.$refs.flow_container).then(canvas => {
        let type = 'png'
        var imgData = canvas.toDataURL(type)
        filer.downloadImage(new Date().getTime() + '.' + type, imgData, type)
      })
    },

    /**
     * @description 重置画布
     */
    handleReset () {
      dialoger.confirm({
        msg: '确定重置吗?'
      }).then(result => {
        if (!result) {
          return false
        }
        this.init()
      })
    },

    /**
     * @description 清空画布
     */
    handleClear () {
      dialoger.confirm({
        msg: '确定清空吗?'
      }).then(result => {
        if (!result) {
          return false
        }
        this.nodeList = []
        this.linkList = []
      })
    }
  },

  mounted () {
    this.init()
  }
}
</script>

<style lang="less">
.super-flow__menu-container .super-flow__menu{position:absolute;outline:none;width:180px;padding:4px 0;border:1px solid #b4b4b4;box-shadow:0 8px 16px 0 rgba(0,0,0,.3);overflow:hidden;border-radius:3px;z-index:10;background-color:#fff;margin:0}.super-flow__menu-container .super-flow__menu-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;width:170px;min-height:26px;line-height:26px;cursor:pointer;position:relative;padding:0 4px}.super-flow__menu-container .super-flow__menu-item:last-child{margin:0}.super-flow__menu-container .super-flow__menu-item:last-child:after{display:none}.super-flow__menu-container .super-flow__menu-item:hover{background-color:#eee}.super-flow__menu-container .super-flow__menu-item-icon{float:left;width:26px;height:26px}.super-flow__menu-container .super-flow__menu-item-content{float:left;display:inline-block;color:#333;font-size:14px;line-height:26px;width:144px;font-weight:400}.super-flow__menu-container .super-flow__menu-item>div{position:absolute;top:0;left:0;right:0;bottom:0}.super-flow__menu-container .super-flow__menu-item.is-disabled{cursor:no-drop}.super-flow__menu-container .super-flow__menu-item.is-disabled>span{color:#999}.super-flow__menu-container .super-flow__menu-item.is-disabled:hover{background-color:transparent}.super-flow__menu-container .super-flow__menu-line{width:100%;margin:4px 0;border-bottom:1px solid #b4b4b4;height:0}.super-flow__menu-container .super-flow__menu-line:last-child{display:none}.super-flow__menu-container .flow__menu-mask{content:"";position:fixed;top:0;bottom:0;right:0;left:0;z-index:10;background-color:transparent}.super-flow__node{box-shadow:1px 2px 8px rgba(0,0,0,.2);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:absolute;background-color:#fff;border:1px solid #b4b4b4;z-index:1;outline:none}.super-flow__node.can-move{cursor:move}.super-flow__node-header{background-color:green}.super-flow__node .node-side{position:absolute;cursor:crosshair}.super-flow__node .node-side-top{top:-5px;right:0;left:0;height:10px}.super-flow__node .node-side-right{top:0;right:-5px;bottom:0;width:10px}.super-flow__node .node-side-bottom{right:0;bottom:-5px;left:0;height:10px}.super-flow__node .node-side-left{top:0;bottom:0;left:-5px;width:10px}.super-flow__node:hover{box-shadow:1px 2px 8px rgba(0,0,0,.4)}.super-flow__node.isSelect{z-index:2}.super-flow__line{position:absolute;z-index:0}.super-flow__line.inPath{cursor:pointer}.super-flow__mark-line{position:absolute;z-index:0;border:1px solid transparent}.super-flow{font-family:Apple System,SF Pro SC,SF Pro Display,Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,STHeiti,Microsoft YaHei,Microsoft JhengHei,Source Han Sans SC,Noto Sans CJK SC,Source Han Sans CN,sans-serif;position:relative;background-color:transparent;width:100%;height:100%;overflow:hidden}.super-flow>.select-all__mask{position:absolute;background-color:rgba(85,175,255,.1);z-index:20;border:1px dashed #55abfc;cursor:move;outline:none}
.super-flow-base-demo {
  width            : 100%;
  height           : 800px;
  margin           : 0 auto;
  background-color : #f5f5f5;

  .super-flow__node {
    .flow-node {
      > header {
        font-size   : 14px;
        height      : 32px;
        line-height : 32px;
        padding     : 0 12px;
        color       : #ffffff;
      }

      > section {
        text-align  : center;
        line-height : 20px;
        overflow    : hidden;
        padding     : 6px 12px;
        word-break  : break-all;
      }

      &.flow-node-start {
        > header {
          background-color : #55abfc;
        }
      }

      &.flow-node-condition {
        > header {
          background-color : #BC1D16;
        }
      }

      &.flow-node-approval {
        > header {
          background-color : rgba(188, 181, 58, 0.76);
        }
      }

      &.flow-node-cc {
        > header {
          background-color : #30b95c;
        }
      }

      &.flow-node-end {
        > header {
          height           : 50px;
          line-height      : 50px;
          background-color : rgb(0, 0, 0);
        }
      }
    }
  }
}
</style>
